package session.stateful;

import com.paypal.sdk.core.nvp.NVPDecoder;
import com.paypal.sdk.core.nvp.NVPEncoder;
import com.paypal.sdk.profiles.APIProfile;
import com.paypal.sdk.profiles.ProfileFactory;
import com.paypal.sdk.services.NVPCallerServices;
import entity.TouristAccountEntity;
import entity.PaymentManagementEntity;
import entity.ReservationEntity;
import entity.StakeholderEntity;
import entity.TransactionsEntity;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
/**
 *
 * @author IS3102
**/
@Stateless
public class PayPalSessionBean {
    
    @PersistenceContext
    private EntityManager entityManager;
    @EJB
    TransactionSessionBean transactionSessionBean;
    @EJB
    TouristSessionBean touristSessionBean;
    @EJB
    ReservationSessionBean reservationSessionBean;
    @EJB
    StakeholderSessionBeanStateful stakeholderSessionBean;  
    private Collection<String> cardTypeList = new ArrayList<String>();   
    private Collection<String> expMonthList = new ArrayList<String>();
    private Collection<String> expYearList = new ArrayList<String>();
    private String hostIp;
    private Long paymentId;
    

    /** Creates a new instance of IAPaymentProcessingManagerBean */
    public PayPalSessionBean() {       
        //System.out.println("email"+ selectedStakeholder.getCorpEmail());
    }

//[PAYMENT]----------------------------------------------------------------------------------------------
    public NVPDecoder DoDirectPaymentCode(String paymentAction, String amount, String cardType,
            String acct, String expdate, String cvv2, String email,
            String firstName, String lastName) {
        NVPEncoder encoder = new NVPEncoder();
        NVPDecoder decoder = new NVPDecoder();

        try {

            NVPCallerServices caller = new NVPCallerServices();
            APIProfile profile = ProfileFactory.createSignatureAPIProfile();

            // Set up your API credentials, PayPal end point, API operation and version.
            profile.setAPIUsername("web_1316757704_biz_api1.gmail.com");
            profile.setAPIPassword("1316757754");
            profile.setSignature("AFcWxV21C7fd0v3bYYYRCpSSRl31AobkBjpaOfK5wRRDT34RrVAP6RfZ");
            profile.setEnvironment("sandbox");
            profile.setSubject("");
            caller.setAPIProfile(profile);

            encoder.add("VERSION", "60.0");
            encoder.add("METHOD", "DoDirectPayment");

            // Add request-specific fields to the request string.
            encoder.add("PAYMENTACTION", paymentAction);
            encoder.add("AMT", amount);
            encoder.add("CREDITCARDTYPE", cardType);
            encoder.add("ACCT", acct);
            encoder.add("EXPDATE", expdate);
            encoder.add("CVV2", cvv2);
            encoder.add("PAYER", email);
            encoder.add("FIRSTNAME", firstName);
            encoder.add("LASTNAME", lastName);

            // Execute the API operation and obtain the response.
            String NVPRequest = encoder.encode();
            String NVPResponse = (String) caller.call(NVPRequest);
            decoder.decode(NVPResponse);

        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return decoder;
    }

    public void usePayPal() throws IOException {
        System.out.println("usePaypalSeesionBean");
        TouristAccountEntity selectedTourist=null;
        StakeholderEntity selectedStakeholder= null;
        ReservationEntity selectedReservation=null;
        PaymentManagementEntity selectedPaymentManagement=null;
        selectedStakeholder= entityManager.find(StakeholderEntity.class, Long.valueOf("1"));
        selectedPaymentManagement= entityManager.find(PaymentManagementEntity.class, Long.valueOf("111"));       
        System.out.println("paymentManagement "+ selectedPaymentManagement.getPaymentLeft());
        
        //HARD code  
        String cardType="Visa";
        String cardNumber="4337054430604796";
        String expMonth="01";
        String expYear="2012";
        String cvv="999";
        String firstName = selectedStakeholder.getCorpName();
        String lastName = selectedStakeholder.getCorpContactPerson();
        String email;             
        String salesAmt=null;
        String expDate = "" + expMonth + expYear;
        String paypalTransactionId=null;
        String paypalCorrelationId=null;
        org.apache.log4j.BasicConfigurator.configure();
        
        if (selectedStakeholder!=null){
            firstName = selectedStakeholder.getCorpName();
            lastName = selectedStakeholder.getCorpContactPerson();
            email= selectedStakeholder.getCorpEmail();
        }
        else{
            firstName = selectedTourist.getTourist().getFirstName();
            lastName = selectedTourist.getTourist().getLastName();
            email= selectedTourist.getTourist().getEmail();      
        }
        System.out.println("Paypal email: " + selectedStakeholder.getCorpEmail());
        
        if (selectedReservation ==null)
            salesAmt=String.valueOf(selectedPaymentManagement.getPaymentLeft());
        else
            salesAmt=String.valueOf(selectedReservation.getDeposit());
        
        NVPDecoder paypalResponse = DoDirectPaymentCode("Sale", salesAmt, cardType, cardNumber,
                expDate, cvv, email, firstName, lastName);

        // ack variable
        boolean success = false;
        String response = "";
        String statusMessage = "";

        for (Object objKey : paypalResponse.getMap().keySet()) {
            System.out.println(objKey.toString() + " = " + paypalResponse.getMap().get(objKey));

            if (objKey.toString().equals("L_LONGMESSAGE0")) {
                statusMessage = (String) paypalResponse.getMap().get(objKey);
            }
            // Ack is a success
            if (objKey.toString().equals("ACK")) {
                response = (String) paypalResponse.getMap().get(objKey);
                if (response.equals("Success")) {
                    success = true;
                }
            }
            if (objKey.toString().equals("TRANSACTIONID")) {
                paypalTransactionId = (String) paypalResponse.getMap().get(objKey);
            }           
            if (objKey.toString().equals("CORRELATIONID")) {
                paypalCorrelationId = (String) paypalResponse.getMap().get(objKey);
            }
        }

        // transaction successful
        if (success == true) {
            // create payment record
            System.out.println("Success");
            System.out.println(salesAmt);
            System.out.println(paypalTransactionId);
            System.out.println(paypalCorrelationId);
            System.out.println(selectedTourist);
            System.out.println(selectedReservation);
            System.out.println(selectedStakeholder);
            System.out.println(selectedPaymentManagement);
            transactionSessionBean.createTransaction(Double.valueOf(salesAmt),"PAYMENT", paypalTransactionId, 
                    paypalCorrelationId, selectedTourist, selectedReservation, selectedStakeholder, selectedPaymentManagement,"");
            
            // go to success page, print receipt
        }
    }
    
//    public void createTransactionEntity(String amount, String description, String paypalTransactionId, String paypalCorrelationId, 
//            TouristAccountEntity tourist, ReservationEntity reservation, StakeholderEntity stakeholder, 
//            PaymentManagementEntity paymentManagement){
//        transactionSessionBean.createTransaction(Double.valueOf(amount),description,paypalTransactionId, paypalCorrelationId,
//                tourist, reservation, stakeholder, paymentManagement);
//    }
    
//[PAYMENT]------------------------------------------------------------------------------------------------

//[REFUND]-------------------------------------------------------------------------------------------------
    public NVPDecoder RefundTransactionCode(String refundType, String transactionId, String amount, String note) {
        NVPEncoder encoder = new NVPEncoder();
        NVPDecoder decoder = new NVPDecoder();
        NVPCallerServices caller = null;

        try {
            caller = new NVPCallerServices();
            APIProfile profile = ProfileFactory.createSignatureAPIProfile();
            /*
            WARNING: Do not embed plaintext credentials in your application code.
            Doing so is insecure and against best practices.
            Your API credentials must be handled securely. Please consider
            encrypting them for use in any production environment, and ensure
            that only authorized individuals may view or modify them.
             */

            // Set up your API credentials, PayPal end point, API operation and version.
            profile.setAPIUsername("web_1316757704_biz_api1.gmail.com");
            profile.setAPIPassword("1316757754");
            profile.setSignature("AFcWxV21C7fd0v3bYYYRCpSSRl31AobkBjpaOfK5wRRDT34RrVAP6RfZ");
            profile.setEnvironment("sandbox");
            profile.setSubject("");
            caller.setAPIProfile(profile);
            encoder.add("VERSION", "60.0");
            encoder.add("METHOD", "RefundTransaction");

            // Add request-specific fields to the request string.
            encoder.add("REFUNDTYPE", refundType);
            encoder.add("TRANSACTIONID", transactionId);
            if ((refundType != null) && (refundType.length() > 0) && (refundType.equalsIgnoreCase("Partial"))) {
                encoder.add("AMT", amount);
            }
            encoder.add("NOTE", note);

            // Execute the API operation and obtain the response.
            String NVPRequest = encoder.encode();
            String NVPResponse = (String) caller.call(NVPRequest);
            decoder.decode(NVPResponse);
        } catch (Exception ex) {

            ex.printStackTrace();
        }
        return decoder;
    }
    
    public void refundPayPal(TransactionsEntity transaction, Double amount, String note, String purpose) throws IOException {
        String paypalTransactionId=null;
        String paypalCorrelationId=null;
        org.apache.log4j.BasicConfigurator.configure();
        
        paypalTransactionId= transaction.getPaypalTransactionId();
        NVPDecoder paypalResponse = RefundTransactionCode("Partial", paypalTransactionId,String.valueOf(amount), note);
        // ack variable
        boolean success = false;
        String response = "";
        String statusMessage = "";

        for (Object objKey : paypalResponse.getMap().keySet()) {
            System.out.println(objKey.toString() + " = " + paypalResponse.getMap().get(objKey));

            if (objKey.toString().equals("L_LONGMESSAGE0")) {
                statusMessage = (String) paypalResponse.getMap().get(objKey);
            }

            // Ack is a success
            if (objKey.toString().equals("ACK")) {
                response = (String) paypalResponse.getMap().get(objKey);
                if (response.equals("Success")) {
                    success = true;
                }
            }
            if (objKey.toString().equals("REFUNDTRANSACTIONID")) {
                paypalTransactionId = (String) paypalResponse.getMap().get(objKey);
            }           
            if (objKey.toString().equals("CORRELATIONID")) {
                paypalCorrelationId = (String) paypalResponse.getMap().get(objKey);
            }
        }
        // transaction successful
        if (success == true) {
            // create payment record
            transactionSessionBean.createTransaction(-1*amount, "REFUND", paypalTransactionId, paypalCorrelationId, 
                    transaction.getTourist(), transaction.getReservation(), transaction.getStakeholder(), transaction.getPaymentManagement(),purpose);
            System.out.println("Refund Successful");
            // go to success page, print receipt
        }
    }
//[REFUND]---------------------------------------------------------------------------------------------------

    public TransactionSessionBean getTransactionSessionBean() {
        return transactionSessionBean;
    }

    public void setTransactionSessionBean(TransactionSessionBean transactionSessionBean) {
        this.transactionSessionBean = transactionSessionBean;
    }

    public TouristSessionBean getTouristSessionBean() {
        return touristSessionBean;
    }

    public void setTouristSessionBean(TouristSessionBean touristSessionBean) {
        this.touristSessionBean = touristSessionBean;
    }

    public ReservationSessionBean getReservationSessionBean() {
        return reservationSessionBean;
    }

    public void setReservationSessionBean(ReservationSessionBean reservationSessionBean) {
        this.reservationSessionBean = reservationSessionBean;
    }

    public Collection<String> getCardTypeList() {
        return cardTypeList;
    }

    public void setCardTypeList(Collection<String> cardTypeList) {
        this.cardTypeList = cardTypeList;
    }

    public Collection<String> getExpMonthList() {
        return expMonthList;
    }

    public void setExpMonthList(Collection<String> expMonthList) {
        this.expMonthList = expMonthList;
    }

    public Collection<String> getExpYearList() {
        return expYearList;
    }

    public void setExpYearList(Collection<String> expYearList) {
        this.expYearList = expYearList;
    }

    public String getHostIp() {
        return hostIp;
    }

    public void setHostIp(String hostIp) {
        this.hostIp = hostIp;
    }

    public Long getPaymentId() {
        return paymentId;
    }

    public void setPaymentId(Long paymentId) {
        this.paymentId = paymentId;
    }

    public StakeholderSessionBeanStateful getStakeholderSessionBean() {
        return stakeholderSessionBean;
    }
}
    
